/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * bocciawii
 * Copyright (C) Grupo de trabajo ULE 2010 <ulewii@googlegroups.com>
 * 
 * bocciawii is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * bocciawii is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "render.h"

Render::Render(opciones_aplicacion* opciones)
{
	_opciones = opciones;

	log = new ErrorLog("RENDER", "", "Render.txt");
	

	camaras = new Camara(0, 0, 2.5, -6);

}

Render::~Render()
{
	camaras->~Camara();
}

int Render::IniciaPantalla()
{
	int flags = SDL_INIT_VIDEO;
	if ( SDL_Init(flags) < 0 ) {
        fprintf(stderr, "IniciaPantalla(): Imposible iniciar SDL: %s\n", SDL_GetError());
        return -1;
	}




	if (_opciones->width == 0 || _opciones->height == 0)
	{
		const SDL_VideoInfo* info = SDL_GetVideoInfo();
		_opciones->width = info->current_w;
		_opciones->height = info->current_h;
	}
	
	aspecto_vertical = 45.0f;
	aspecto_horizontal = GLfloat(_opciones->width)/GLfloat(_opciones->height);
	znear = 1.0f;
	zfar = 100.0f;






	
	
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
	antialiasing = 1;
	pantalla = SDL_SetVideoMode(_opciones->width, _opciones->height, 0, SDL_VIDEO_FLAGS);

	if (pantalla == NULL)
	{
		std::cerr << "Antialias no disponible" << std::endl;
		antialiasing = 0;
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
		pantalla = SDL_SetVideoMode(_opciones->width, _opciones->height, 0, SDL_VIDEO_FLAGS);
	}
		
	if( pantalla == NULL)
	{
		//TODO Gestión de errores SDL/HW
		log->log(LOG_ERROR, "IniciaPantalla() - Fallo %ix%i-%i: %s", 
							 _opciones->width, _opciones->height, 0, SDL_GetError());
		
		return -1;
	}
	SDL_WM_SetCaption("BocciaWii", "BocciaWii");

	log->log(LOG_MENSAJE, "IniciaPantalla() - Ventana %ix%i - %i BPP", 
							_opciones->width, _opciones->height, 0);
	return 0;

}

void Render::InitLights()
{
	glPushMatrix();
	int num_luces = GL_LIGHT2;
	GLfloat LightAmbient[]  = {1.0f, 1.0f, 1.0f, 1.0f}; 
	GLfloat LightDiffuse[]  = {1.0f, 1.0f, 1.0f, 1.0f}; 
	GLfloat LightSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};

	GLfloat LightPosition[num_luces - GL_LIGHT0][4];
	LightPosition[0] = {15.0f, 6.0f, 22.0f, 1.0f};
	LightPosition[1] = {15.0f, 6.0f, -22.0f, 1.0f};

	GLfloat LightDirection[num_luces - GL_LIGHT0][3];
	LightDirection[0] = {-0.552f, -0.1987f, -0.81f};
	LightDirection[1] = {-0.552f, -0.1987f, +0.81f};
	GLfloat LightCutoff = 60.0f;
	

	for (int i = GL_LIGHT0; i < num_luces; i++)
	{

		glLightfv(i, GL_AMBIENT, LightAmbient);
		glLightfv(i, GL_DIFFUSE, LightDiffuse);
		glLightfv(i, GL_SPECULAR, LightSpecular);
		glLightfv(i, GL_POSITION, LightPosition[i-GL_LIGHT0]);
		
		glLightf(i, GL_SPOT_CUTOFF, LightCutoff);
		
		glLightfv(i, GL_SPOT_DIRECTION, LightDirection[i-GL_LIGHT0]);
		
		glEnable(i);
		
	}


	GLfloat LightGlobalPos[4] = {1.0f, 1.0f, 1.0f, 0.0f};
	GLfloat LightGlobalAmb[4] = {1.0f, 1.0f, 1.0f, 1.0f};
	GLfloat LightGlobalDif[4] = {1.0f, 1.0f, 1.0f, 1.0f};
	GLfloat LightGlobalEsp[4] = {1.0f, 1.0f, 1.0f, 1.0f};
	glLightfv(num_luces, GL_POSITION, LightGlobalPos);
	glLightfv(num_luces, GL_AMBIENT, LightGlobalAmb);
	glLightfv(num_luces, GL_DIFFUSE, LightGlobalDif);
	glEnable(num_luces);

	num_luces++;
	
	
	GLfloat LightGlobalPos2[4] = {-1.0f, 1.0f, -1.0f, 0.0f};
	glLightfv(num_luces, GL_POSITION, LightGlobalPos2);
	glLightfv(num_luces, GL_AMBIENT, LightGlobalAmb);
	glLightfv(num_luces, GL_DIFFUSE, LightGlobalDif);
	//glLightfv(num_luces, GL_SPECULAR, LightGlobalEsp);
	glEnable(num_luces);

//	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
//	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
	glEnable(GL_LIGHTING);

	glPopMatrix();
}

void Render::InitSDLGL()
{

	glViewport(0, 0, _opciones->width, _opciones->height);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepth(1.0);

    glDepthFunc(GL_NICEST);
    glEnable(GL_DEPTH_TEST);

	glShadeModel(GL_SMOOTH);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    gluPerspective(aspecto_vertical,aspecto_horizontal,znear,zfar);
	


	
    glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	InitLights();


	if (antialiasing)
	{
		glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
		glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
		glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
		glEnable (GL_LINE_SMOOTH);
		glEnable(GL_POLYGON_SMOOTH);
		glEnable(GL_POINT_SMOOTH);
	}

	
}

void Render::Mirar()
{
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	
	camaras->Mirar();
	
	InitLights();
	
}


void Render::Mostrar()
{
	SDL_GL_SwapBuffers();
}
